/*
 ------------------------------------------------------------------------------
 Copyright (C) 2006-2007 Team Blur.

 This file is part of the Quantum Engine source code.

 The Quantum Engine source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Quantum Engine source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Quantum Engine source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


#ifndef __MSGSYSTEM_H__
#define __MSGSYSTEM_H__


/*
 ==============================================================================

 Message I/O:

 No memory is allocated, so the data buffer set with MSG_Init must be in static
 memory. If dynamically allocated memory is used, it should not be freed until
 all message I/O is completed.

 Byte ordering and alignment is handled automatically.

 It is safe to write to and read from a message buffer at the same time.

 ==============================================================================
*/

class ByteBuffer{
public:
	// Initializes a message buffer for writing and/or reading
							ByteBuffer(){};
							ByteBuffer(byte *data, int size, bool allowOverflow);
	void					Init(byte *data, int size, bool allowOverflow);

	// Writing functions
	void					ClearWriteState();
	void					SetWriteState(int bits);

	void					WriteBits(int value, int bits);

	void					WriteBool(bool value);
	void					WriteChar(int value);
	void					WriteByte(int value);
	void					WriteShort(int value);
	void					WriteLong(int value);
	void					WriteFloat(float value);
	void					WriteAngle8(float angle);
	void					WriteAngle16(float angle);
	void					WriteDir(const odVec3 &dir);
	void					WriteString(const char *string);
	void					WriteData(const void *data, int size);

	void					WriteDeltaChar(int oldValue, int newValue);
	void					WriteDeltaByte(int oldValue, int newValue);
	void					WriteDeltaShort(int oldValue, int newValue);
	void					WriteDeltaLong(int oldValue, int newValue);
	void					WriteDeltaFloat(float oldValue, float newValue);
	void					WriteDeltaAngle8(float oldAngle, float newAngle);
	void					WriteDeltaAngle16(float oldAngle, float newAngle);
	void					WriteDeltaDir(const odVec3 &oldDir, const odVec3 &newDir);

	// Reading functions
	void					ClearReadState();
	void					SetReadState(int bits);

	int						ReadBits(int bits);

	bool					ReadBool();
	int						ReadChar();
	int						ReadByte();
	int						ReadShort();
	int						ReadLong();
	float					ReadFloat();
	float					ReadAngle8();
	float					ReadAngle16();
	odVec3					ReadDir();
	int						ReadString(char *string, int size);
	int						ReadData(void *data, int size);

	int						ReadDeltaChar(int oldValue);
	int						ReadDeltaByte(int oldValue);
	int						ReadDeltaShort(int oldValue);
	int						ReadDeltaLong(int oldValue);
	float					ReadDeltaFloat(float oldValue);
	float					ReadDeltaAngle8(float oldAngle);
	float					ReadDeltaAngle16(float oldAngle);
	odVec3					ReadDeltaDir(const odVec3 &oldDir);

	int		getSize(){return size;}
	int		getBitsWritten(){return writeCount;}
	int		getBytesWritten(){return writeBytes;}
	int		getBitsRead(){return readCount;}
	int		getBytesRead(){return readBytes;}
public:
	byte* 					data;				// Pointer to message data
	int						size;				// Size of message data buffer
	bool					allowOverflow;		// If false, throw an error when overflowed
	bool					overflowed;			// Set to true when overflowed

	int						writeCount;			// Number of bits written so far
	int						writeBytes;			// Number of bytes written so far
	int						writeBit;			// Current bit in last written byte

	int						readCount;			// Number of bits read so far
	int						readBytes;			// Number of bytes read so far
	int						readBit;			// Current bit in last read byte
};

#endif	// __MSGSYSTEM_H__
